package com.siyoumi.util;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class XApp {
    /**
     * 通过指定有效的时长（秒）生成过期时间。
     *
     * @param seconds 有效时长（秒）。
     * @return ISO8601 时间字符串，如："2014-12-01T12:00:00.000Z"。
     */
    public static String secondsToIso6801(long seconds) {
        // 获取当前时间戳（以秒为单位）
        long now = Instant.now().getEpochSecond();
        // 计算过期时间的时间戳
        long expirationTime = now + seconds;
        // 将时间戳转换为Instant对象，并格式化为ISO8601格式
        Instant instant = Instant.ofEpochSecond(expirationTime);
        // 定义时区为UTC
        ZoneId zone = ZoneOffset.UTC;
        // 将 Instant 转换为 ZonedDateTime
        ZonedDateTime zonedDateTime = instant.atZone(zone);
        // 定义日期时间格式，例如2023-12-03T13:00:00.000Z
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        // 格式化日期时间
        return zonedDateTime.format(formatter);
    }

    static public List<String> getWeeks() {
        //["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
        String[] weeks = {
                "星期一",
                "星期二",
                "星期三",
                "星期四",
                "星期五",
                "星期六",
                "星期日",
        };

        return Arrays.asList(weeks);
    }

    /**
     * 雪花
     */
    //static public Long getID() {
    //    XSnowflake sf = XSnowflake.create(0);
    //    return sf.nextId();
    //}
    //
    //static public String getStrID() {
    //    return getStrID("");
    //}
    //
    //static public String getStrID(String prefix) {
    //    return prefix + getID();
    //}

    /**
     * uuid
     */
    static public String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private static Random rnd = new Random();

    /**
     * 随机数
     *
     * @param min 最小值
     * @param max 最大值
     * @return 随机结果
     */
    @SneakyThrows
    static public int random(int min, int max) {
        if (max < min) {
            throw new Exception("max < min");
        }
        Integer rnd_max = max - min;
        if (min < 0) {
            //负数随机
            rnd_max = max + Math.abs(min);
        }
        //+1原因
        //传2，随机结果0-1
        //传10，随机结果0-9
        rnd_max++;
        if (rnd_max <= 0) {
            return 0;
        }

        int i = XApp.rnd.nextInt(rnd_max) + min;
        //log.debug("min: {} ,max: {}  = random (0 - {}) + {} = {}", min, max, rnd_max - 1, min, i);

        return i;
    }

    /**
     * 随机生成x位的数字
     *
     * @param x 位数需要范围1-10
     */
    static public int random(int x) {
        if (x < 1) {
            return 0;
        }
        if (x > 10) {
            x = 10;
        }

        //1,1-9
        //2,10-99
        //3,100-999
        String[] beginArr = new String[x];
        beginArr[0] = "1";
        for (int i = 1; i < x; i++) {
            beginArr[i] = "0";
        }
        String beginStr = Arrays.stream(beginArr).collect(Collectors.joining(""));
        Integer begin = XStr.toInt(beginStr);
        int end = (begin * 10) - 1;
        log.info("begin: {}", begin);
        log.info("end: {}", end);

        return random(begin, end);
    }

    /**
     * 密码加密串
     */
    static public String encPwd(String x, String pwd) {
        String str1 = String.format("%s|%s", x, pwd);
        String encPwd = XStr.md5(str1).toUpperCase();
        log.debug("encPwd: {}", encPwd);
        return encPwd;
    }


    /**
     * 单位元 转 分（支付，退款用）
     *
     * @param n
     */
    static public Long decimalToFee(BigDecimal n) {
        BigDecimal n100 = BigDecimal.valueOf(100);
        return n.multiply(n100).longValue();
    }

    /**
     * 除100
     * 93.999 转 0.930
     * 12.123 转 0.121
     *
     * @param n
     */
    static public BigDecimal decimal100(BigDecimal n) {
        return n.divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
    }

    /**
     * 0.44999999 转 0.440
     *
     * @param n
     */
    static public BigDecimal toDecimalPay(BigDecimal n) {
        if (n == null) {
            n = new BigDecimal("0");
        }
        return n.setScale(2, RoundingMode.DOWN);
    }


    /**
     * 停x秒
     *
     * @param s
     */
    static public void sleep(int s) {
        sleepMs(s * 1000);
    }

    /**
     * 停x毫秒
     *
     * @param ms
     */
    static public void sleepMs(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * win环境
     */
    static public Boolean isWindows() {
        return System.getProperty("os.name")
                .toLowerCase().startsWith("windows");
    }
}
